﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace PSE.Framework.Versions.Engine
{
    public class Proxy<TChannel>
    {
        #region [ Singleton ]
        private static object _lock = new object();
        private static Proxy<TChannel> _instance;
        public static Proxy<TChannel> Instance
        {
            get
            {
                lock (_lock)
                {
                    if (_instance == null)
                        _instance = new Proxy<TChannel>();

                    return _instance;
                }
            }
        }
        #endregion [ Singleton ]


        public void Connect(string serviceUrl, Action<TChannel> action)
        {
            ChannelFactory<TChannel> serviceChannel = null;
            NetTcpBinding bindings = CreateNetTcpBinding();

            try
            {
                string url = string.Format("net.tcp://{0}/PSEComponents/Versions/Service/LocalDiscovery.svc", serviceUrl);
                using (ChannelFactory<TChannel> channel = new ChannelFactory<TChannel>(bindings, url))
                {
                    TChannel client = channel.CreateChannel();
                    action(client);
                }
            }
            catch (EndpointNotFoundException ex)
            {
                
            }
            catch (CommunicationException ex)
            {
                
            }
            catch (Exception ex)
            {
                
            }
            finally
            {
                try
                {
                    if (serviceChannel != null && serviceChannel.State != CommunicationState.Faulted)
                        serviceChannel.Close();
                }
                catch
                {
                    serviceChannel.Abort();
                }
            }
        }

        private NetTcpBinding CreateNetTcpBinding()
        {
            int value = 2147483647;

            NetTcpBinding binding = new NetTcpBinding();
            binding.Security.Mode = SecurityMode.None;
            binding.SendTimeout = new TimeSpan(0, 10, 0);
            binding.OpenTimeout = new TimeSpan(0, 10, 0);
            binding.CloseTimeout = new TimeSpan(0, 10, 0);
            binding.ReceiveTimeout = new TimeSpan(0, 10, 0);

            binding.MaxBufferPoolSize = value;
            binding.MaxBufferSize = value;
            binding.ReaderQuotas.MaxArrayLength = value;
            binding.MaxReceivedMessageSize = value;

            return binding;
        }
    }
}